package com.banggood.upms.service.impl;

import com.banggood.silk.web.api.exception.SkbException;
import com.banggood.upms.bean.exception.ExceptionEnum;
import com.banggood.upms.bean.po.Permission;
import com.banggood.upms.bean.po.Tree;
import com.banggood.upms.bean.po.User;
import com.banggood.upms.bean.po.UserTree;
import com.banggood.upms.bean.vo.UserPermissionVo;
import com.banggood.upms.bean.vo.UserTreeVo;
import com.banggood.upms.bean.vo.search.TreePermissionSearchCriteria;
import com.banggood.upms.dao.*;
import com.banggood.upms.service.UserTreeService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * @author XuChuangFeng
 */
@Service
@Transactional(rollbackFor = SkbException.class)
public class UserTreeServiceImpl extends BaseServiceImpl<UserTree, UserTreeDao> implements UserTreeService {

    protected final Log logger = LogFactory.getLog(getClass());

    @Override
    @Autowired
    public void setDao(UserTreeDao dao) {
        super.dao = dao;
    }
    @Autowired
    private UserDao userDao;
    @Autowired
    private SystemDao systemDao;
    @Autowired
    private TreeDao treeDao;
    @Autowired
    private PermissionDao permissionDao;
    @Autowired
    private TreeTreeDao treeTreeDao;

    @Override
    public List<UserTree> selectByUserIdAndTreeType(UserTreeVo vo) {
        return dao.selectByUserIdAndTreeType(vo);
    }

    @Override
    public String adjustUserTrees(String treeType, String userId, List<UserTree> posForInsert, List<String> idsForRemove) {
        String brief = this.insertUserTrees(posForInsert);
        if(!CollectionUtils.isEmpty(idsForRemove)) {
            for(String id : idsForRemove) {
                dao.deleteByPrimaryKey(id);
                logger.debug("用户删除的树节点主键：" + id);
            }
        }
        StringBuffer buffer= new StringBuffer(brief);
        buffer.append("删除了").append(idsForRemove.size()).append("个节点映射。");
        return buffer.toString();
    }

    @Override
    public String insertUserTrees(List<UserTree> posForInsert) {
        for(UserTree po : posForInsert) {
            this.fillTreePath(po);
            dao.insert(po);
            logger.debug("用户新增的树节点主键：" + po.getTreeId());
        }
        return new StringBuffer().append("本次操作为该用户新增了").append(posForInsert.size()).append("个节点配置。").toString();
    }

    @Override
    public String deleteAll(UserTreeVo vo) {
        int count = dao.deleteByTreeType(vo);
        StringBuffer buffer = new StringBuffer();
        buffer.append("本次一共删除了").append(count).append("个用户与节点配置。");
        return buffer.toString();
    }

    @Override
    public List<Permission> selectUserPerms(UserPermissionVo vo) throws Exception {
        if(StringUtils.isEmpty(vo.getAccountName()) && StringUtils.isEmpty(vo.getUserId())) {
            throw new SkbException(ExceptionEnum.USER_PERM_SEARCH_PARM_INVALID.getCode(), ExceptionEnum.USER_PERM_SEARCH_PARM_INVALID.getMessage());
        }
        // 如果只是传入用户账号，则将用户账号转换成用户id，dao层根据用户id进行搜索
        User user = null;
        if(StringUtils.isEmpty(vo.getUserId())) {
            user = userDao.selectByAccount(vo.getAccountName());
            vo.setUserId(user.getUserId());
        } else {
            user = userDao.selectByPrimaryKey(vo.getUserId());
        }
        if(user == null) {
            throw new SkbException(ExceptionEnum.USER_NOT_EXISTS.getCode(), ExceptionEnum.USER_NOT_EXISTS.getMessage());
        }
        // 获取当前用户直接分配的树节点
        List<String> treeIds = dao.selectTreeIdsByUserId(vo.getUserId());
        if(CollectionUtils.isEmpty(treeIds)) {
            return null;
        }
        // 若树ID集合里面有岗位树类型JOB的节点，那么还需要查询这些岗位树节点是否有分配角色树节点
        this.fillRoleTreeNodeId(treeIds);
        // 把搜索条件系统code转成系统id
        if(StringUtils.isEmpty(vo.getSystemId()) && !StringUtils.isEmpty(vo.getSystemCode())) {
            vo.setSystemId(systemDao.selectBySystemCode(vo.getSystemCode()).getSystemId());
        }
        TreePermissionSearchCriteria criteria = new TreePermissionSearchCriteria();
        criteria.setTreeIds(treeIds);
        criteria.setSystemId(vo.getSystemId());
        List<Permission> permissions = permissionDao.selectBySystemIdAndTreeIds(criteria);
        return permissions;
    }

    private void fillRoleTreeNodeId(List<String> treeIds) {
        List<String> jobTypeIds = treeDao.filterNonJobNodeId(treeIds);
        // 不存在岗位树节点ID
        if(CollectionUtils.isEmpty(jobTypeIds)) {
            return;
        }
        List<String> roleTypeIds = treeTreeDao.selectRoleTreeIdsByJobTypeIds(jobTypeIds);
        if(CollectionUtils.isEmpty(roleTypeIds)) {
            return;
        }
        for(String id : roleTypeIds) {
            if(!treeIds.contains(id)) {
                treeIds.add(id);
            }
        }
    }

    @Override
    public List<User> selectUsersByTreeId(String id) throws Exception {
        Tree tree = treeDao.selectByPrimaryKey(id);
        if(tree == null) {
            throw new SkbException(ExceptionEnum.NODE_NOT_EXISTS.getCode(), ExceptionEnum.NODE_NOT_EXISTS.getMessage());
        }
        List<String> ids = dao.selectAssignedUserIdsByTreeId(id);
        if(CollectionUtils.isEmpty(ids)) {
            return null;
        }
        // 去除重复的id，数据库已经进行除重，注释掉这里
//        List<String> uniqueIds = new ArrayList<>(new HashSet<>(ids));
        List<User> users = userDao.selectByPrimaryKeys(ids);
        return users;
    }

    private void fillTreePath(UserTree userTree) {
        Tree tree = treeDao.selectByPrimaryKey(userTree.getTreeId());
        userTree.setPath(tree.getPath());
    }
}
